<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue + Cesium 原生时间轴播放</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script src="https://cesium.com/downloads/cesiumjs/releases/1.132/Build/Cesium/Cesium.js"></script>
    <link href="https://cesium.com/downloads/cesiumjs/releases/1.132/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
    <style>
        body { margin: 0; padding: 0; font-family: Arial, sans-serif; }
        #app { width: 100%; height: 100vh; }
        #cesiumContainer { width: 100%; height: 100vh; }
        .info {
            position: absolute; top: 10px; left: 10px; z-index: 1000;
            background: rgba(0,0,0,0.8); color: #fff; padding: 14px; border-radius: 6px; max-width: 520px;
        }
        .row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 8px; }
        .row button { background: #4CAF50; color: #fff; border: none; padding: 6px 12px; border-radius: 4px; cursor: pointer; font-size: 12px; }
        .row button:hover { background: #45a049; }
        .row button.danger { background: #e84c3d; }
        .row button.danger:hover { background: #cf3e30; }
        .row button:disabled { background: #666; cursor: not-allowed; }
        .row select, .row input { padding: 4px 6px; font-size: 12px; }
        .kv { font-size: 12px; line-height: 1.6; }
        .kv b { color: #ffd666; }
        .timeline { display:flex; align-items:center; gap:8px; margin-top:6px; }
        .timeline input[type="range"] { width: 240px; }
        
        /* 右侧表格样式 */
        .geojson-table {
            position: absolute; top: 10px; right: 10px; z-index: 1000;
            background: rgba(0,0,0,0.9); color: #fff; padding: 14px; border-radius: 6px;
            width: 400px; max-height: 80vh; overflow-y: auto;
        }
        .geojson-table h3 { margin: 0 0 12px 0; color: #ffd666; font-size: 14px; }
        .geojson-table table { width: 100%; border-collapse: collapse; font-size: 11px; }
        .geojson-table th, .geojson-table td { 
            padding: 6px 8px; text-align: left; border-bottom: 1px solid #333; 
        }
        .geojson-table th { background: rgba(255,255,255,0.1); font-weight: bold; }
        .geojson-table tr:hover { background: rgba(255,255,255,0.05); }
        .geojson-table .actions { display: flex; gap: 4px; }
        .geojson-table .actions button { 
            padding: 2px 6px; font-size: 10px; background: #2196F3; 
            border: none; color: white; border-radius: 3px; cursor: pointer; 
        }
        .geojson-table .actions button:hover { background: #1976D2; }
        .geojson-table .actions button.danger { background: #f44336; }
        .geojson-table .actions button.danger:hover { background: #d32f2f; }
        .geojson-table .json-preview { 
            max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; 
        }
    </style>
</head>
<body>
<div id="app">
    <div id="cesiumContainer"></div>
    <div class="info">
        <div class="kv">状态：<b>{{ status }}</b></div>
                 <div class="row">
             <label>选择轨迹：
                 <select v-model.number="currentTrackIndex" @change="setCurrentTrack(currentTrackIndex)">
                     <option :value="0">轨迹1 (红色)</option>
                     <option :value="1">轨迹2 (蓝色)</option>
                     <option :value="2">轨迹3 (绿色)</option>
                     <option :value="3">轨迹4 (黄色)</option>
                 </select>
             </label>
             <label>时间轴模式
                 <select v-model="timeMode" @change="applyTimeMode">
                     <option value="utc-now">方案A：实时UTC（起点=现在）</option>
                     <option value="relative-fixed">方案B：相对秒（固定起点并缩放Timeline）</option>
                 </select>
             </label>
         </div>
                 <div class="row">
            <button @click="play">开始</button>
            <button @click="pause" :disabled="!playing">暂停</button>
            <button @click="reset">重置</button>
            <button @click="nudge(-5)">快退5s</button>
            <button @click="nudge(5)">快进5s</button>
            <label>倍速
                <select v-model.number="speed" @change="applySpeed">
                    <option :value="-4">-4x</option>
                    <option :value="-2">-2x</option>
                    <option :value="-1">-1x</option>
                    <option :value="0.5">0.5x</option>
                    <option :value="1">1x</option>
                    <option :value="2">2x</option>
                    <option :value="4">4x</option>
                </select>
            </label>
        </div>
        <div class="row">
            <button @click="startDrawPolygon" :disabled="drawing">开始绘制多边形</button>
            <button @click="finishDrawPolygon" :disabled="!drawing">完成</button>
            <button @click="clearDrawPolygon" class="danger">清空多边形</button>
            <span style="font-size:12px;color:#ccc">提示：左键落点、移动预览、右键完成。</span>
        </div>
        <div class="row timeline">
            <span>{{ currentSec.toFixed(1) }}s</span>
            <input type="range"
                   :min="0"
                   :max="endSeconds"
                   step="0.1"
                   :value="currentSec"
                   @input="onSliderInput"
                   @change="onSliderChange"
                   @mousedown="isSeeking=true" @mouseup="isSeeking=false" @mouseleave="isSeeking=false"
                   @touchstart="isSeeking=true" @touchend="isSeeking=false">
            <span>{{ endSeconds }}s</span>
        </div>
        <div class="kv">当前位置：<b>{{ posText }}</b></div>
        <div class="kv">当前区段：<b>{{ segText }}</b></div>
        <div class="kv" v-if="polygonGeoJSON">
            <div style="margin-top: 8px;">
                <strong style="color: #ffd666;">多边形GeoJSON：</strong>
                <button @click="copyGeoJSON" style="margin-left: 8px; background: #2196F3; color: white; border: none; padding: 2px 6px; border-radius: 3px; font-size: 10px; cursor: pointer;">复制</button>
            </div>
            <pre style="background: rgba(0,0,0,0.3); padding: 8px; border-radius: 4px; font-size: 10px; max-height: 120px; overflow-y: auto; margin-top: 4px; white-space: pre-wrap; word-break: break-all;">{{ polygonGeoJSON }}</pre>
        </div>
    </div>
    
    <!-- 右侧GeoJSON记录表格 -->
    <div class="geojson-table">
        <h3>GeoJSON记录 ({{ geojsonRecords.length }})</h3>
        <table v-if="geojsonRecords.length > 0">
            <thead>
                <tr>
                    <th>序号</th>
                    <th>时间</th>
                    <th>点数</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(record, index) in geojsonRecords" :key="index">
                    <td>{{ index + 1 }}</td>
                    <td>{{ formatTime(record.timestamp) }}</td>
                    <td>{{ record.pointCount }}</td>
                    <td class="actions">
                        <button @click="copyRecordGeoJSON(index)" title="复制GeoJSON">复制</button>
                        <button @click="viewRecordGeoJSON(index)" title="查看完整GeoJSON">查看</button>
                        <button @click="deleteRecord(index)" class="danger" title="删除记录">删除</button>
                    </td>
                </tr>
            </tbody>
        </table>
        <div v-else style="text-align: center; color: #999; padding: 20px;">
            暂无绘制记录
        </div>
    </div>
</div>

<script>
const { createApp } = Vue;
createApp({
    data() {
        return {
            status: '正在初始化...',
            viewer: null,
            entity: null,
            trackEntity: null,
            positionProp: null,
            start: null,
            end: null,
            playing: false,
            speed: 1,
            jumpSec: 0,
            currentSec: 0,
            endSeconds: 0,
            posText: '-',
            segText: '-',
                         timeMode: 'relative-fixed',
            isSeeking: false,
            // 4条轨迹数据
            flightTracks: [
                // 轨迹1
                {
                    id: 'b12341da-dc4a-4118-a56a-20cb945f6c91',
                    color: Cesium.Color.RED,
                    points: [
                        { longitude: 120.111792521, latitude: 30.2472879540001, altitude: 0, name: '轨迹1起点', timestamp: 0 },
                        { longitude: 120.117795, latitude: 30.249504, altitude: 100, name: '轨迹1点1', timestamp: 69 },
                        { longitude: 120.119117, latitude: 30.25194, altitude: 100, name: '轨迹1点2', timestamp: 94 },
                        { longitude: 120.119544, latitude: 30.25938, altitude: 100, name: '轨迹1点3', timestamp: 165 },
                        { longitude: 120.121162, latitude: 30.263412, altitude: 100, name: '轨迹1点4', timestamp: 207 },
                        { longitude: 120.119557, latitude: 30.263946, altitude: 100, name: '轨迹1点5', timestamp: 221 },
                        { longitude: 120.120528, latitude: 30.266352, altitude: 100, name: '轨迹1点6', timestamp: 246 },
                        { longitude: 120.118622, latitude: 30.268716, altitude: 100, name: '轨迹1点7', timestamp: 279 },
                        { longitude: 120.119819, latitude: 30.271879, altitude: 100, name: '轨迹1点8', timestamp: 312 },
                        { longitude: 120.112325, latitude: 30.274745, altitude: 100, name: '轨迹1点9', timestamp: 384 },
                        { longitude: 120.10759, latitude: 30.273569, altitude: 100, name: '轨迹1点10', timestamp: 424 },
                        { longitude: 120.107057, latitude: 30.275237, altitude: 100, name: '轨迹1点11', timestamp: 441 },
                        { longitude: 120.09107, latitude: 30.272086, altitude: 100, name: '轨迹1点12', timestamp: 581 },
                        { longitude: 120.092704, latitude: 30.266666, altitude: 100, name: '轨迹1点13', timestamp: 636 },
                        { longitude: 120.071865, latitude: 30.262915, altitude: 100, name: '轨迹1点14', timestamp: 818 },
                        { longitude: 120.054096, latitude: 30.254919, altitude: 100, name: '轨迹1点15', timestamp: 988 },
                        { longitude: 120.049636, latitude: 30.250876, altitude: 100, name: '轨迹1点16', timestamp: 1043 },
                        { longitude: 120.039332, latitude: 30.249163, altitude: 100, name: '轨迹1点17', timestamp: 1133 },
                        { longitude: 120.041942, latitude: 30.24129, altitude: 100, name: '轨迹1点18', timestamp: 1213 },
                        { longitude: 120.046272, latitude: 30.234794, altitude: 100, name: '轨迹1点19', timestamp: 1286 },
                        { longitude: 120.041702, latitude: 30.230204, altitude: 100, name: '轨迹1点20', timestamp: 1344 },
                        { longitude: 120.036808, latitude: 30.227474, altitude: 100, name: '轨迹1点21', timestamp: 1394 },
                        { longitude: 120.023628, latitude: 30.221137, altitude: 100, name: '轨迹1点22', timestamp: 1523 },
                        { longitude: 120.021126, latitude: 30.221503, altitude: 100, name: '轨迹1点23', timestamp: 1548 },
                        { longitude: 120.019704, latitude: 30.218845, altitude: 100, name: '轨迹1点24', timestamp: 1576 },
                        { longitude: 120.016752, latitude: 30.218045, altitude: 100, name: '轨迹1点25', timestamp: 1603 },
                        { longitude: 120.016727, latitude: 30.215634, altitude: 100, name: '轨迹1点26', timestamp: 1626 },
                        { longitude: 120.014747, latitude: 30.21463, altitude: 100, name: '轨迹1点27', timestamp: 1646 },
                        { longitude: 120.015624, latitude: 30.213564, altitude: 100, name: '轨迹1点28', timestamp: 1659 },
                        { longitude: 120.01072, latitude: 30.209679, altitude: 100, name: '轨迹1点29', timestamp: 1715 },
                        { longitude: 119.999299, latitude: 30.209789, altitude: 100, name: '轨迹1点30', timestamp: 1814 },
                        { longitude: 119.985726, latitude: 30.205768, altitude: 100, name: '轨迹1点31', timestamp: 1937 },
                        { longitude: 119.97871, latitude: 30.213116, altitude: 100, name: '轨迹1点32', timestamp: 2032 },
                        { longitude: 119.978142, latitude: 30.227244, altitude: 100, name: '轨迹1点33', timestamp: 2185 },
                        { longitude: 119.971754, latitude: 30.225768, altitude: 100, name: '轨迹1点34', timestamp: 2241 },
                        { longitude: 119.966495, latitude: 30.230789, altitude: 100, name: '轨迹1点35', timestamp: 2307 },
                        { longitude: 119.958876, latitude: 30.231575, altitude: 100, name: '轨迹1点36', timestamp: 2373 },
                        { longitude: 119.951303, latitude: 30.236698, altitude: 100, name: '轨迹1点37', timestamp: 2453 },
                        { longitude: 119.948499, latitude: 30.241622, altitude: 100, name: '轨迹1点38', timestamp: 2507 },
                        { longitude: 119.943255, latitude: 30.239525, altitude: 100, name: '轨迹1点39', timestamp: 2557 },
                        { longitude: 119.940625, latitude: 30.243488, altitude: 100, name: '轨迹1点40', timestamp: 2602 },
                        { longitude: 119.93825, latitude: 30.243168, altitude: 100, name: '轨迹1点41', timestamp: 2623 },
                        { longitude: 119.934173, latitude: 30.249783, altitude: 100, name: '轨迹1点42', timestamp: 2698 },
                        { longitude: 119.923651, latitude: 30.244602, altitude: 100, name: '轨迹1点43', timestamp: 2802 },
                        { longitude: 119.924027, latitude: 30.241337, altitude: 100, name: '轨迹1点44', timestamp: 2834 },
                        { longitude: 119.925584, latitude: 30.241494, altitude: 100, name: '轨迹1点45', timestamp: 2847 },
                        { longitude: 119.924312, latitude: 30.232191, altitude: 100, name: '轨迹1点46', timestamp: 2940 },
                        { longitude: 119.925623, latitude: 30.228686, altitude: 100, name: '轨迹1点47', timestamp: 2976 },
                        { longitude: 119.923481, latitude: 30.22635, altitude: 100, name: '轨迹1点48', timestamp: 3005 },
                        { longitude: 119.923758, latitude: 30.224634, altitude: 100, name: '轨迹1点49', timestamp: 3022 },
                        { longitude: 119.928704, latitude: 30.217638, altitude: 100, name: '轨迹1点50', timestamp: 3105 },
                        { longitude: 119.921602, latitude: 30.206258, altitude: 100, name: '轨迹1点51', timestamp: 3232 },
                        { longitude: 119.914301, latitude: 30.2021, altitude: 100, name: '轨迹1点52', timestamp: 3307 },
                        { longitude: 119.909252, latitude: 30.196447, altitude: 100, name: '轨迹1点53', timestamp: 3379 },
                        { longitude: 119.908338428, latitude: 30.1974326440001, altitude: 0, name: '轨迹1终点', timestamp: 3401 }
                    ]
                },
                // 轨迹2
                {
                    id: 'a782d9e6-fab9-4b71-810f-f2f690ad8428',
                    color: Cesium.Color.BLUE,
                    points: [
                        { longitude: 120.373808317, latitude: 30.3229924830001, altitude: 0, name: '轨迹2起点', timestamp: 0 },
                        { longitude: 120.374732, latitude: 30.32299, altitude: 100, name: '轨迹2点1', timestamp: 17 },
                        { longitude: 120.374725, latitude: 30.320965, altitude: 100, name: '轨迹2点2', timestamp: 37 },
                        { longitude: 120.373048, latitude: 30.316547, altitude: 100, name: '轨迹2点3', timestamp: 83 },
                        { longitude: 120.369228, latitude: 30.313237, altitude: 100, name: '轨迹2点4', timestamp: 146 },
                        { longitude: 120.353416, latitude: 30.312865, altitude: 100, name: '轨迹2点5', timestamp: 282 },
                        { longitude: 120.353419, latitude: 30.315633, altitude: 100, name: '轨迹2点6', timestamp: 309 },
                        { longitude: 120.350735, latitude: 30.3156, altitude: 100, name: '轨迹2点7', timestamp: 331 },
                        { longitude: 120.350415, latitude: 30.318073, altitude: 100, name: '轨迹2点8', timestamp: 355 },
                        { longitude: 120.334208, latitude: 30.318141, altitude: 100, name: '轨迹2点9', timestamp: 492 },
                        { longitude: 120.334018, latitude: 30.320362, altitude: 100, name: '轨迹2点10', timestamp: 513 },
                        { longitude: 120.332014, latitude: 30.321125, altitude: 100, name: '轨迹2点11', timestamp: 534 },
                        { longitude: 120.32019, latitude: 30.319719, altitude: 100, name: '轨迹2点12', timestamp: 633 },
                        { longitude: 120.320387, latitude: 30.317461, altitude: 100, name: '轨迹2点13', timestamp: 655 },
                        { longitude: 120.314334, latitude: 30.31723, altitude: 100, name: '轨迹2点14', timestamp: 707 },
                        { longitude: 120.314276, latitude: 30.309647, altitude: 100, name: '轨迹2点15', timestamp: 782 },
                        { longitude: 120.301343, latitude: 30.3052, altitude: 100, name: '轨迹2点16', timestamp: 900 },
                        { longitude: 120.294787, latitude: 30.311669, altitude: 100, name: '轨迹2点17', timestamp: 984 },
                        { longitude: 120.286225, latitude: 30.312592, altitude: 100, name: '轨迹2点18', timestamp: 1057 },
                        { longitude: 120.286611, latitude: 30.314928, altitude: 100, name: '轨迹2点19', timestamp: 1080 },
                        { longitude: 120.279656, latitude: 30.315778, altitude: 100, name: '轨迹2点20', timestamp: 1140 },
                        { longitude: 120.280696, latitude: 30.315652, altitude: 100, name: '轨迹2点21', timestamp: 1149 },
                        { longitude: 120.27995, latitude: 30.310696, altitude: 100, name: '轨迹2点22', timestamp: 1198 },
                        { longitude: 120.273986, latitude: 30.311316, altitude: 100, name: '轨迹2点23', timestamp: 1249 },
                        { longitude: 120.271642, latitude: 30.310642, altitude: 100, name: '轨迹2点24', timestamp: 1270 },
                        { longitude: 120.271295, latitude: 30.30894, altitude: 100, name: '轨迹2点25', timestamp: 1287 },
                        { longitude: 120.265657, latitude: 30.309481, altitude: 100, name: '轨迹2点26', timestamp: 1335 },
                        { longitude: 120.264557, latitude: 30.305479, altitude: 100, name: '轨迹2点27', timestamp: 1376 },
                        { longitude: 120.26108, latitude: 30.306095, altitude: 100, name: '轨迹2点28', timestamp: 1406 },
                        { longitude: 120.25568, latitude: 30.298029, altitude: 100, name: '轨迹2点29', timestamp: 1497 },
                        { longitude: 120.252832, latitude: 30.300164, altitude: 100, name: '轨迹2点30', timestamp: 1529 },
                        { longitude: 120.242224, latitude: 30.291733, altitude: 100, name: '轨迹2点31', timestamp: 1650 },
                        { longitude: 120.233969, latitude: 30.290019, altitude: 100, name: '轨迹2点32', timestamp: 1722 },
                        { longitude: 120.231666, latitude: 30.292157, altitude: 100, name: '轨迹2点33', timestamp: 1751 },
                        { longitude: 120.233399, latitude: 30.293743, altitude: 100, name: '轨迹2点34', timestamp: 1772 },
                        { longitude: 120.226652, latitude: 30.296595, altitude: 100, name: '轨迹2点35', timestamp: 1835 },
                        { longitude: 120.227348, latitude: 30.303357, altitude: 100, name: '轨迹2点36', timestamp: 1903 },
                        { longitude: 120.230182, latitude: 30.308501, altitude: 100, name: '轨迹2点37', timestamp: 1963 },
                        { longitude: 120.228717, latitude: 30.308623, altitude: 100, name: '轨迹2点38', timestamp: 1976 },
                        { longitude: 120.225893, latitude: 30.31748, altitude: 100, name: '轨迹2点39', timestamp: 2067 },
                        { longitude: 120.232235, latitude: 30.318331, altitude: 100, name: '轨迹2点40', timestamp: 2120 },
                        { longitude: 120.23241, latitude: 30.322229, altitude: 100, name: '轨迹2点41', timestamp: 2163 },
                        { longitude: 120.2308, latitude: 30.322173, altitude: 100, name: '轨迹2点42', timestamp: 2176 },
                        { longitude: 120.231165, latitude: 30.320587, altitude: 100, name: '轨迹2点43', timestamp: 2191 },
                        { longitude: 120.216534, latitude: 30.321346, altitude: 100, name: '轨迹2点44', timestamp: 2316 },
                        { longitude: 120.22057982206334, latitude: 30.32815130027842, altitude: 100, name: '轨迹2点45', timestamp: 2392 },
                        { longitude: 120.226191, latitude: 30.328607, altitude: 30, name: '轨迹2点46', timestamp: 2406 },
                        { longitude: 120.230281, latitude: 30.33402, altitude: 30, name: '轨迹2点47', timestamp: 2424 },
                        { longitude: 120.2259105788186, latitude: 30.33521187420664, altitude: 30, name: '轨迹2点48', timestamp: 2435 },
                        { longitude: 120.229481, latitude: 30.339917, altitude: 100, name: '轨迹2点49', timestamp: 2452 },
                        { longitude: 120.221675, latitude: 30.348065, altitude: 100, name: '轨迹2点50', timestamp: 2483 },
                        { longitude: 120.222681, latitude: 30.349972, altitude: 100, name: '轨迹2点51', timestamp: 2489 },
                        { longitude: 120.228728, latitude: 30.350441, altitude: 100, name: '轨迹2点52', timestamp: 2504 },
                        { longitude: 120.223804, latitude: 30.359546, altitude: 100, name: '轨迹2点53', timestamp: 2532 },
                        { longitude: 120.224336, latitude: 30.361494, altitude: 100, name: '轨迹2点54', timestamp: 2538 },
                        { longitude: 120.220742, latitude: 30.365233, altitude: 100, name: '轨迹2点55', timestamp: 2552 },
                        { longitude: 120.226035, latitude: 30.367, altitude: 100, name: '轨迹2点56', timestamp: 2566 },
                        { longitude: 120.225242721, latitude: 30.3680246480001, altitude: 0, name: '轨迹2终点', timestamp: 2569 }
                    ]
                },
                // 轨迹3
                {
                    id: '2be0c9c7-b7dd-4930-8ba3-a36779ed8d20',
                    color: Cesium.Color.GREEN,
                    points: [
                        { longitude: 120.373808317, latitude: 30.3229924830001, altitude: 0, name: '轨迹3起点', timestamp: 0 },
                        { longitude: 120.374732, latitude: 30.32299, altitude: 100, name: '轨迹3点1', timestamp: 17 },
                        { longitude: 120.374725, latitude: 30.320965, altitude: 100, name: '轨迹3点2', timestamp: 37 },
                        { longitude: 120.373048, latitude: 30.316547, altitude: 100, name: '轨迹3点3', timestamp: 83 },
                        { longitude: 120.369228, latitude: 30.313237, altitude: 100, name: '轨迹3点4', timestamp: 146 },
                        { longitude: 120.353416, latitude: 30.312865, altitude: 100, name: '轨迹3点5', timestamp: 282 },
                        { longitude: 120.353419, latitude: 30.315633, altitude: 100, name: '轨迹3点6', timestamp: 309 },
                        { longitude: 120.350735, latitude: 30.3156, altitude: 100, name: '轨迹3点7', timestamp: 331 },
                        { longitude: 120.350415, latitude: 30.318073, altitude: 100, name: '轨迹3点8', timestamp: 355 },
                        { longitude: 120.334208, latitude: 30.318141, altitude: 100, name: '轨迹3点9', timestamp: 492 },
                        { longitude: 120.334018, latitude: 30.320362, altitude: 100, name: '轨迹3点10', timestamp: 513 },
                        { longitude: 120.332014, latitude: 30.321125, altitude: 100, name: '轨迹3点11', timestamp: 534 },
                        { longitude: 120.32019, latitude: 30.319719, altitude: 100, name: '轨迹3点12', timestamp: 633 },
                        { longitude: 120.320387, latitude: 30.317461, altitude: 100, name: '轨迹3点13', timestamp: 655 },
                        { longitude: 120.314334, latitude: 30.31723, altitude: 100, name: '轨迹3点14', timestamp: 707 },
                        { longitude: 120.314276, latitude: 30.309647, altitude: 100, name: '轨迹3点15', timestamp: 782 },
                        { longitude: 120.301343, latitude: 30.3052, altitude: 100, name: '轨迹3点16', timestamp: 900 },
                        { longitude: 120.294787, latitude: 30.311669, altitude: 100, name: '轨迹3点17', timestamp: 984 },
                        { longitude: 120.286225, latitude: 30.312592, altitude: 100, name: '轨迹3点18', timestamp: 1057 },
                        { longitude: 120.286611, latitude: 30.314928, altitude: 100, name: '轨迹3点19', timestamp: 1080 },
                        { longitude: 120.279656, latitude: 30.315778, altitude: 100, name: '轨迹3点20', timestamp: 1140 },
                        { longitude: 120.280696, latitude: 30.315652, altitude: 100, name: '轨迹3点21', timestamp: 1149 },
                        { longitude: 120.27995, latitude: 30.310696, altitude: 100, name: '轨迹3点22', timestamp: 1198 },
                        { longitude: 120.273986, latitude: 30.311316, altitude: 100, name: '轨迹3点23', timestamp: 1249 },
                        { longitude: 120.271642, latitude: 30.310642, altitude: 100, name: '轨迹3点24', timestamp: 1270 },
                        { longitude: 120.271295, latitude: 30.30894, altitude: 100, name: '轨迹3点25', timestamp: 1287 },
                        { longitude: 120.265657, latitude: 30.309481, altitude: 100, name: '轨迹3点26', timestamp: 1335 },
                        { longitude: 120.264557, latitude: 30.305479, altitude: 100, name: '轨迹3点27', timestamp: 1376 },
                        { longitude: 120.26108, latitude: 30.306095, altitude: 100, name: '轨迹3点28', timestamp: 1406 },
                        { longitude: 120.25568, latitude: 30.298029, altitude: 100, name: '轨迹3点29', timestamp: 1497 },
                        { longitude: 120.252832, latitude: 30.300164, altitude: 100, name: '轨迹3点30', timestamp: 1529 },
                        { longitude: 120.242224, latitude: 30.291733, altitude: 100, name: '轨迹3点31', timestamp: 1650 },
                        { longitude: 120.233969, latitude: 30.290019, altitude: 100, name: '轨迹3点32', timestamp: 1722 },
                        { longitude: 120.231666, latitude: 30.292157, altitude: 100, name: '轨迹3点33', timestamp: 1751 },
                        { longitude: 120.233399, latitude: 30.293743, altitude: 100, name: '轨迹3点34', timestamp: 1772 },
                        { longitude: 120.226652, latitude: 30.296595, altitude: 100, name: '轨迹3点35', timestamp: 1835 },
                        { longitude: 120.227348, latitude: 30.303357, altitude: 100, name: '轨迹3点36', timestamp: 1903 },
                        { longitude: 120.230182, latitude: 30.308501, altitude: 100, name: '轨迹3点37', timestamp: 1963 },
                        { longitude: 120.228717, latitude: 30.308623, altitude: 100, name: '轨迹3点38', timestamp: 1976 },
                        { longitude: 120.225893, latitude: 30.31748, altitude: 100, name: '轨迹3点39', timestamp: 2067 },
                        { longitude: 120.232235, latitude: 30.318331, altitude: 100, name: '轨迹3点40', timestamp: 2120 },
                        { longitude: 120.23241, latitude: 30.322229, altitude: 100, name: '轨迹3点41', timestamp: 2163 },
                        { longitude: 120.2308, latitude: 30.322173, altitude: 100, name: '轨迹3点42', timestamp: 2176 },
                        { longitude: 120.231165, latitude: 30.320587, altitude: 100, name: '轨迹3点43', timestamp: 2191 },
                        { longitude: 120.216534, latitude: 30.321346, altitude: 100, name: '轨迹3点44', timestamp: 2316 },
                        { longitude: 120.22057982206334, latitude: 30.32815130027842, altitude: 100, name: '轨迹3点45', timestamp: 2392 },
                        { longitude: 120.226191, latitude: 30.328607, altitude: 30, name: '轨迹3点46', timestamp: 2406 },
                        { longitude: 120.230281, latitude: 30.33402, altitude: 30, name: '轨迹3点47', timestamp: 2424 },
                        { longitude: 120.2259105788186, latitude: 30.33521187420664, altitude: 30, name: '轨迹3点48', timestamp: 2435 },
                        { longitude: 120.229481, latitude: 30.339917, altitude: 100, name: '轨迹3点49', timestamp: 2452 },
                        { longitude: 120.221675, latitude: 30.348065, altitude: 100, name: '轨迹3点50', timestamp: 2483 },
                        { longitude: 120.222681, latitude: 30.349972, altitude: 100, name: '轨迹3点51', timestamp: 2489 },
                        { longitude: 120.228728, latitude: 30.350441, altitude: 100, name: '轨迹3点52', timestamp: 2504 },
                        { longitude: 120.223804, latitude: 30.359546, altitude: 100, name: '轨迹3点53', timestamp: 2532 },
                        { longitude: 120.224336, latitude: 30.361494, altitude: 100, name: '轨迹3点54', timestamp: 2538 },
                        { longitude: 120.220742, latitude: 30.365233, altitude: 100, name: '轨迹3点55', timestamp: 2552 },
                        { longitude: 120.226035, latitude: 30.367, altitude: 100, name: '轨迹3点56', timestamp: 2566 },
                        { longitude: 120.225242721, latitude: 30.3680246480001, altitude: 0, name: '轨迹3终点', timestamp: 2569 }
                    ]
                },
                // 轨迹4
                {
                    id: '171493bb-3bef-435c-9e8b-bda42878e40d',
                    color: Cesium.Color.YELLOW,
                    points: [
                        { longitude: 120.199662221, latitude: 30.2674388090001, altitude: 0, name: '轨迹4起点', timestamp: 0 },
                        { longitude: 120.199361, latitude: 30.265998, altitude: 100, name: '轨迹4点1', timestamp: 39 },
                        { longitude: 120.206639, latitude: 30.265537, altitude: 100, name: '轨迹4点2', timestamp: 155 },
                        { longitude: 120.206806, latitude: 30.26335, altitude: 100, name: '轨迹4点3', timestamp: 193 },
                        { longitude: 120.211882, latitude: 30.26389, altitude: 100, name: '轨迹4点4', timestamp: 270 },
                        { longitude: 120.21459, latitude: 30.265772, altitude: 100, name: '轨迹4点5', timestamp: 322 },
                        { longitude: 120.216916, latitude: 30.263643, altitude: 100, name: '轨迹4点6', timestamp: 372 },
                        { longitude: 120.22984, latitude: 30.275203, altitude: 100, name: '轨迹4点7', timestamp: 648 },
                        { longitude: 120.227552, latitude: 30.276995, altitude: 100, name: '轨迹4点8', timestamp: 694 },
                        { longitude: 120.228919, latitude: 30.278664, altitude: 100, name: '轨迹4点9', timestamp: 733 },
                        { longitude: 120.227059, latitude: 30.280537, altitude: 100, name: '轨迹4点10', timestamp: 775 },
                        { longitude: 120.230844, latitude: 30.283575, altitude: 100, name: '轨迹4点11', timestamp: 851 },
                        { longitude: 120.232823, latitude: 30.282007, altitude: 100, name: '轨迹4点12', timestamp: 891 },
                        { longitude: 120.241214, latitude: 30.289724, altitude: 100, name: '轨迹4点13', timestamp: 1073 },
                        { longitude: 120.239583, latitude: 30.291178, altitude: 100, name: '轨迹4点14', timestamp: 1108 },
                        { longitude: 120.242224, latitude: 30.291733, altitude: 100, name: '轨迹4点15', timestamp: 1148 },
                        { longitude: 120.252832, latitude: 30.300164, altitude: 100, name: '轨迹4点16', timestamp: 1361 },
                        { longitude: 120.25568, latitude: 30.298029, altitude: 100, name: '轨迹4点17', timestamp: 1417 },
                        { longitude: 120.26108, latitude: 30.306095, altitude: 100, name: '轨迹4点18', timestamp: 1577 },
                        { longitude: 120.264557, latitude: 30.305479, altitude: 100, name: '轨迹4点19', timestamp: 1629 },
                        { longitude: 120.265657, latitude: 30.309481, altitude: 100, name: '轨迹4点20', timestamp: 1700 },
                        { longitude: 120.271295, latitude: 30.30894, altitude: 100, name: '轨迹4点21', timestamp: 1784 },
                        { longitude: 120.271642, latitude: 30.310642, altitude: 100, name: '轨迹4点22', timestamp: 1814 },
                        { longitude: 120.273986, latitude: 30.311316, altitude: 100, name: '轨迹4点23', timestamp: 1851 },
                        { longitude: 120.27995, latitude: 30.310696, altitude: 100, name: '轨迹4点24', timestamp: 1940 },
                        { longitude: 120.280696, latitude: 30.315652, altitude: 100, name: '轨迹4点25', timestamp: 2026 },
                        { longitude: 120.276447, latitude: 30.31617, altitude: 100, name: '轨迹4点26', timestamp: 2090 },
                        { longitude: 120.276668, latitude: 30.317911, altitude: 100, name: '轨迹4点27', timestamp: 2120 },
                        { longitude: 120.272485, latitude: 30.317375, altitude: 100, name: '轨迹4点28', timestamp: 2183 },
                        { longitude: 120.273588, latitude: 30.321905, altitude: 100, name: '轨迹4点29', timestamp: 2263 },
                        { longitude: 120.270456, latitude: 30.322272, altitude: 100, name: '轨迹4点30', timestamp: 2310 },
                        { longitude: 120.26644, latitude: 30.330133, altitude: 100, name: '轨迹4点31', timestamp: 2472 },
                        { longitude: 120.27037301, latitude: 30.332085401, altitude: 0, name: '轨迹4终点', timestamp: 2547 }
                    ]
                }
            ],
            // 当前选中的轨迹（用于播放）
            currentTrackIndex: 0,
            flightPath: [], // 将根据选中的轨迹动态设置
                         // 为每条轨迹创建独立的飞机实体
             aircraftEntities: [], // 存储每条轨迹的飞机实体
             // 绘制相关
             drawing: false,
             drawPositions: [], // Cartesian3
             drawPolygonEntity: null,
             drawOutlineEntity: null,
             drawHandler: null,
             polygonGeoJSON: null, // 存储多边形的GeoJSON
             geojsonRecords: [] // 存储所有GeoJSON记录
        };
    },
    computed: { clock() { return this.viewer ? this.viewer.clock : null; } },
    mounted() { this.initCesium(); },
    methods: {
        // 安全缩放到目标：兼容 Promise / 非 Promise 返回
        safeZoomTo(target) {
            try {
                const res = this.viewer.zoomTo(target);
                if (res && typeof res.then === 'function') {
                    res.catch(() => {
                        this.viewer.camera.setView({
                            destination: Cesium.Cartesian3.fromDegrees(116.4074, 39.9042, 2000000),
                            orientation: { heading: 0.0, pitch: -Cesium.Math.PI_OVER_TWO, roll: 0.0 }
                        });
                    });
                }
            } catch (_) {
                this.viewer.camera.setView({
                    destination: Cesium.Cartesian3.fromDegrees(116.4074, 39.9042, 2000000),
                    orientation: { heading: 0.0, pitch: -Cesium.Math.PI_OVER_TWO, roll: 0.0 }
                });
            }
        },
        // 将相机定位到轨迹第一个点位置
        focusFirstPoint() {
            if (!this.flightPath || this.flightPath.length === 0) return;
            const p0 = this.flightPath[0];
            const height = Math.max(30000, (p0.altitude || 0) + 80000);
            this.viewer.camera.setView({
                destination: Cesium.Cartesian3.fromDegrees(p0.longitude, p0.latitude, height),
                orientation: { heading: 0.0, pitch: -Cesium.Math.PI_OVER_TWO + 0.2, roll: 0.0 }
            });
        },
        initCesium() {
            try {
                this.viewer = new Cesium.Viewer('cesiumContainer', {
                    terrain: Cesium.Terrain.fromWorldTerrain(),
                    animation: true, timeline: true,
                    baseLayerPicker: true, geocoder: true, homeButton: true,
                    sceneModePicker: true, navigationHelpButton: true,
                    fullscreenButton: true, infoBox: true, selectionIndicator: true
                });
                this.viewer.scene.globe.depthTestAgainstTerrain = false;
                
                // 绘制所有4条轨迹
                this.drawAllTracks();
                
                // 为所有轨迹创建飞机实体
                this.createAllAircraftEntities();
                
                // 设置当前轨迹为第一条，但使用最小时间范围
                this.currentTrackIndex = 0;
                this.flightPath = this.flightTracks[0].points;
                this.endSeconds = this.getMinTimeRange(); // 使用最小时间范围
                this.applyTimeMode();
                
                // 首次加载：直接定位到第一个轨迹点
                this.focusFirstPoint();

                this.clock.onTick.addEventListener(this.onTick);
                this.status = '已就绪：显示4条轨迹，可选择轨迹进行播放';
            } catch (e) { this.status = '初始化失败'; console.error(e); }
        },
        
        // 绘制所有轨迹
        drawAllTracks() {
            this.flightTracks.forEach((track, index) => {
                const flat = [];
                for (const p of track.points) { 
                    flat.push(p.longitude, p.latitude, p.altitude); 
                }
                
                this.viewer.entities.add({
                    polyline: {
                        positions: Cesium.Cartesian3.fromDegreesArrayHeights(flat),
                        width: 3,
                        material: track.color.withAlpha(0.8),
                        clampToGround: false
                    }
                });
                
                // 在起点添加标签
                if (track.points.length > 0) {
                    const startPoint = track.points[0];
                    this.viewer.entities.add({
                        position: Cesium.Cartesian3.fromDegrees(startPoint.longitude, startPoint.latitude, startPoint.altitude),
                        label: {
                            text: `轨迹${index + 1}`,
                            font: '12pt sans-serif',
                            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                            outlineWidth: 2,
                            verticalOrigin: Cesium.VerticalOrigin.TOP,
                            pixelOffset: new Cesium.Cartesian2(0, 10),
                            fillColor: track.color,
                            outlineColor: Cesium.Color.BLACK
                        }
                    });
                }
            });
        },
        
        // 设置当前轨迹
        setCurrentTrack(trackIndex) {
            this.currentTrackIndex = trackIndex;
            this.flightPath = this.flightTracks[trackIndex].points;
            this.endSeconds = this.getMinTimeRange(); // 使用最小时间范围
            this.applyTimeMode();
            this.status = `已选择轨迹${trackIndex + 1}，可进行播放控制（时间范围：0-${this.endSeconds}s）`;
        },
        
        // 获取所有轨迹中的最小时间范围
        getMinTimeRange() {
            let minEndSeconds = Infinity;
            this.flightTracks.forEach(track => {
                const endSeconds = track.points[track.points.length - 1].timestamp;
                if (endSeconds < minEndSeconds) {
                    minEndSeconds = endSeconds;
                }
            });
            return minEndSeconds;
        },
        
        // 为所有轨迹创建飞机实体
        createAllAircraftEntities() {
            // 清除之前的飞机实体
            this.aircraftEntities.forEach(entity => {
                if (entity) this.viewer.entities.remove(entity);
            });
            this.aircraftEntities = [];
            
            // 为每条轨迹创建飞机实体
            this.flightTracks.forEach((track, index) => {
                const entity = this.createAircraftEntity(track, index);
                this.aircraftEntities.push(entity);
            });
        },
        
        // 为单条轨迹创建飞机实体
        createAircraftEntity(track, trackIndex) {
            const start = Cesium.JulianDate.fromDate(new Date(Date.UTC(2025, 7, 28, 0, 0, 0)));
            const minEndSeconds = this.getMinTimeRange(); // 使用最小时间范围
            const end = Cesium.JulianDate.addSeconds(start, minEndSeconds, new Cesium.JulianDate());
            
            const positionProp = new Cesium.SampledPositionProperty();
            for (const p of track.points) {
                const t = Cesium.JulianDate.addSeconds(start, p.timestamp, new Cesium.JulianDate());
                const pos = Cesium.Cartesian3.fromDegrees(p.longitude, p.latitude, p.altitude);
                positionProp.addSample(t, pos);
            }
            
            return this.viewer.entities.add({
                availability: new Cesium.TimeIntervalCollection([
                    new Cesium.TimeInterval({ start: start, stop: end })
                ]),
                position: positionProp,
                orientation: new Cesium.VelocityOrientationProperty(positionProp),
                point: { 
                    pixelSize: 15, 
                    color: track.color, 
                    outlineColor: Cesium.Color.WHITE, 
                    outlineWidth: 2 
                },
                label: { 
                    text: `飞机${trackIndex + 1}`, 
                    font: '12pt sans-serif', 
                    style: Cesium.LabelStyle.FILL_AND_OUTLINE, 
                    outlineWidth: 2,
                    verticalOrigin: Cesium.VerticalOrigin.BOTTOM, 
                    pixelOffset: new Cesium.Cartesian2(0, -30),
                    fillColor: track.color, 
                    outlineColor: Cesium.Color.BLACK 
                }
            });
        },
        applyTimeMode() {
            if (this.timeMode === 'relative-fixed') {
                this.start = Cesium.JulianDate.fromDate(new Date(Date.UTC(2025, 7, 28, 0, 0, 0)));
            } else {
                this.start = Cesium.JulianDate.now();
            }
            this.end = Cesium.JulianDate.addSeconds(this.start, this.endSeconds, new Cesium.JulianDate());
            this.clock.startTime = this.start.clone();
            this.clock.stopTime = this.end.clone();
            this.clock.currentTime = this.start.clone();
            this.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
            this.clock.multiplier = this.speed;
            this.clock.shouldAnimate = false;

            if (this.timeMode === 'relative-fixed') {
                this.viewer.timeline.zoomTo(this.start, this.end);
            }
        },
        onTick() {
            // 拖动期间不回写，避免来回拉扯
            if (this.isSeeking) return;
            const secs = Math.max(0, Math.min(this.endSeconds, Cesium.JulianDate.secondsDifference(this.clock.currentTime, this.start)));
            // 对齐到 0.1 步长，避免浮点抖动
            this.currentSec = Math.round(secs * 10) / 10;
            
            // 显示当前选中轨迹的信息
            if (this.flightPath && this.flightPath.length > 0) {
                let idx = 0;
                for (let i = 0; i < this.flightPath.length - 1; i++) {
                    const a = this.flightPath[i].timestamp, b = this.flightPath[i + 1].timestamp;
                    if (secs >= a && secs <= b) { idx = i; break; }
                }
                const A = this.flightPath[idx], B = this.flightPath[Math.min(idx + 1, this.flightPath.length - 1)];
                const span = Math.max(1e-6, B.timestamp - A.timestamp);
                const segProg = Math.min(1, Math.max(0, (secs - A.timestamp) / span));
                const lon = A.longitude + (B.longitude - A.longitude) * segProg;
                const lat = A.latitude + (B.latitude - A.latitude) * segProg;
                this.posText = `轨迹${this.currentTrackIndex + 1}: ${lon.toFixed(2)}, ${lat.toFixed(2)}`;
                this.segText = `${A.name}(${A.timestamp}s) → ${B.name}(${B.timestamp}s)`;
            }
        },
        play() {
            // 无论当前状态如何，都从起点重播
            this.clock.shouldAnimate = false;
            this.clock.currentTime = this.start.clone();
            this.currentSec = 0;
            this.playing = true;
            this.clock.shouldAnimate = true;
            this.status = '播放中（从头开始）';
            // 定位到第一个点
            this.focusFirstPoint();
        },
        pause() { this.clock.shouldAnimate = false; this.playing = false; this.status = '已暂停'; },
        reset() { this.pause(); this.clock.currentTime = this.start.clone(); this.safeZoomTo(this.trackEntity); this.status = '已重置到起点'; },
        applySpeed() { this.clock.multiplier = this.speed; },
        nudge(delta) {
            let t = Cesium.JulianDate.addSeconds(this.clock.currentTime, delta, new Cesium.JulianDate());
            if (Cesium.JulianDate.lessThan(t, this.start)) t = this.start.clone();
            if (Cesium.JulianDate.greaterThan(t, this.end)) t = this.end.clone();
            this.clock.currentTime = t;
        },
        seekSlider(evt) { const sec = Math.max(0, Math.min(this.endSeconds, Number(evt.target.value))); this.seekTo(sec); },
        seekTo(sec) { const clamped = Math.max(0, Math.min(this.endSeconds, Number(sec) || 0)); this.clock.currentTime = Cesium.JulianDate.addSeconds(this.start, clamped, new Cesium.JulianDate()); },
        onSliderInput(evt) {
            this.isSeeking = true;
            const sec = Math.max(0, Math.min(this.endSeconds, Number(evt.target.value)));
            // 只更新UI，不立即改 clock
            this.currentSec = Math.round(sec * 10) / 10;
        },
                 onSliderChange(evt) {
             const sec = Math.max(0, Math.min(this.endSeconds, Number(evt.target.value)));
             this.seekTo(Math.round(sec * 10) / 10);
             // 释放拖动锁
             this.isSeeking = false;
         },
         
         // ================= 多边形绘制 =================
         startDrawPolygon() {
             if (this.drawing) return;
             this.drawing = true;
             this.drawPositions = [];
             if (this.drawPolygonEntity) { this.viewer.entities.remove(this.drawPolygonEntity); this.drawPolygonEntity = null; }
             if (this.drawOutlineEntity) { this.viewer.entities.remove(this.drawOutlineEntity); this.drawOutlineEntity = null; }
             if (this.drawHandler) { this.drawHandler.destroy(); this.drawHandler = null; }
             this.drawHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas);

             // 左键点击：落点
             this.drawHandler.setInputAction((movement) => {
                 const cart = this.getCartesianFromMouse(movement.position);
                 if (!cart) return;
                 this.drawPositions.push(cart);
                 this.ensureDynamicPolygon();
             }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

             // 右键点击：完成绘制
             this.drawHandler.setInputAction((movement) => {
                 if (this.drawing && this.drawPositions.length >= 3) {
                     this.finishDrawPolygon();
                 }
             }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

             // 移动：动态预览末点
             this.drawHandler.setInputAction((movement) => {
                 if (!this.drawing || this.drawPositions.length === 0) return;
                 const cart = this.getCartesianFromMouse(movement.endPosition);
                 if (!cart) return;
                 const temp = this.drawPositions.slice();
                 temp.push(cart);
                 this.updateDynamicPolygon(temp);
             }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
         },
         finishDrawPolygon() {
             if (!this.drawing) return;
             this.drawing = false;
             if (this.drawHandler) { this.drawHandler.destroy(); this.drawHandler = null; }
             // 最终以 drawPositions 生成实体
             if (this.drawPositions.length < 3) return;
             this.updateDynamicPolygon(this.drawPositions, true);
         },
         clearDrawPolygon() {
             this.drawing = false;
             this.drawPositions = [];
             this.polygonGeoJSON = null; // 清除GeoJSON
             
             // 清除所有记录及其对应的实体
             for (const record of this.geojsonRecords) {
                 if (record.polygonEntity) {
                     this.viewer.entities.remove(record.polygonEntity);
                 }
                 if (record.outlineEntity) {
                     this.viewer.entities.remove(record.outlineEntity);
                 }
             }
             this.geojsonRecords = []; // 清空记录数组
             
             if (this.drawHandler) { this.drawHandler.destroy(); this.drawHandler = null; }
             if (this.drawPolygonEntity) { this.viewer.entities.remove(this.drawPolygonEntity); this.drawPolygonEntity = null; }
             if (this.drawOutlineEntity) { this.viewer.entities.remove(this.drawOutlineEntity); this.drawOutlineEntity = null; }
         },
         getCartesianFromMouse(winPos) {
             if (!winPos) return null;
             const scene = this.viewer.scene;
             let cartesian = null;
             if (scene.pickPositionSupported) {
                 cartesian = scene.pickPosition(winPos);
             }
             if (!Cesium.defined(cartesian)) {
                 const ray = this.viewer.camera.getPickRay(winPos);
                 cartesian = scene.globe.pick(ray, scene);
             }
             return cartesian || null;
         },
         ensureDynamicPolygon() {
             if (this.drawPolygonEntity) return;
             const hierarchyCb = new Cesium.CallbackProperty(() => {
                 const list = (this._previewPositions || this.drawPositions);
                 if (!list || list.length < 3) return null;
                 return new Cesium.PolygonHierarchy(list);
             }, false);
             this.drawPolygonEntity = this.viewer.entities.add({
                 polygon: {
                     hierarchy: hierarchyCb,
                     material: Cesium.Color.fromBytes(255, 165, 0, 100), // 橙色半透明
                     perPositionHeight: true,
                     outline: false
                 }
             });
             this.drawOutlineEntity = this.viewer.entities.add({
                 polyline: {
                     positions: new Cesium.CallbackProperty(() => {
                         const list = (this._previewPositions || this.drawPositions);
                         if (!list || list.length < 2) return [];
                         return list.concat(list[0]); // 闭合预览
                     }, false),
                     width: 2,
                     material: Cesium.Color.ORANGE
                 }
             });
         },
         updateDynamicPolygon(positions, finalize = false) {
             this._previewPositions = positions;
             if (finalize) {
                 // 清除预览实体
                 if (this.drawPolygonEntity) { this.viewer.entities.remove(this.drawPolygonEntity); this.drawPolygonEntity = null; }
                 if (this.drawOutlineEntity) { this.viewer.entities.remove(this.drawOutlineEntity); this.drawOutlineEntity = null; }
                 this._previewPositions = null;
                 
                 // 生成GeoJSON（会自动创建实体并添加到记录中）
                 this.generateGeoJSON(positions);
             }
         },
         
         // 生成GeoJSON
         generateGeoJSON(positions) {
             if (!positions || positions.length < 3) {
                 this.polygonGeoJSON = null;
                 return;
             }
             
             // 将Cartesian3坐标转换为经纬度
             const coordinates = [];
             for (const pos of positions) {
                 const cartographic = Cesium.Cartographic.fromCartesian(pos);
                 const longitude = Cesium.Math.toDegrees(cartographic.longitude);
                 const latitude = Cesium.Math.toDegrees(cartographic.latitude);
                 coordinates.push([longitude, latitude]);
             }
             
             // 闭合多边形（首尾相连）
             if (coordinates.length > 0) {
                 coordinates.push(coordinates[0]);
             }
             
             const geojson = {
                 type: "Feature",
                 properties: {
                     name: "绘制多边形",
                     timestamp: new Date().toISOString()
                 },
                 geometry: {
                     type: "Polygon",
                     coordinates: [coordinates]
                 }
             };
             
             this.polygonGeoJSON = JSON.stringify(geojson, null, 2);
             
             // 添加到记录表格
             this.geojsonRecords.push({
                 timestamp: new Date(),
                 pointCount: positions.length,
                 geojson: geojson,
                 geojsonString: this.polygonGeoJSON,
                 polygonEntity: null, // 将在下面设置
                 outlineEntity: null  // 将在下面设置
             });
             
             // 获取刚添加的记录索引
             const recordIndex = this.geojsonRecords.length - 1;
             
             // 创建多边形实体并保存引用
             const polygonEntity = this.viewer.entities.add({
                 polygon: {
                     hierarchy: new Cesium.PolygonHierarchy(positions),
                     material: Cesium.Color.fromBytes(255, 165, 0, 100),
                     perPositionHeight: true
                 }
             });
             
             const outlineEntity = this.viewer.entities.add({
                 polyline: {
                     positions: positions.concat(positions[0]),
                     width: 2,
                     material: Cesium.Color.ORANGE
                 }
             });
             
             // 保存实体引用到记录中
             this.geojsonRecords[recordIndex].polygonEntity = polygonEntity;
             this.geojsonRecords[recordIndex].outlineEntity = outlineEntity;
         },
         
         // 复制GeoJSON到剪贴板
         copyGeoJSON() {
             if (!this.polygonGeoJSON) return;
             
             navigator.clipboard.writeText(this.polygonGeoJSON).then(() => {
                 // 临时显示复制成功提示
                 const btn = event.target;
                 const originalText = btn.textContent;
                 btn.textContent = '已复制';
                 btn.style.background = '#4CAF50';
                 setTimeout(() => {
                     btn.textContent = originalText;
                     btn.style.background = '#2196F3';
                 }, 1000);
             }).catch(err => {
                 console.error('复制失败:', err);
                 // 降级方案：使用传统方法
                 const textArea = document.createElement('textarea');
                 textArea.value = this.polygonGeoJSON;
                 document.body.appendChild(textArea);
                 textArea.select();
                 document.execCommand('copy');
                 document.body.removeChild(textArea);
                 
                 const btn = event.target;
                 const originalText = btn.textContent;
                 btn.textContent = '已复制';
                 btn.style.background = '#4CAF50';
                 setTimeout(() => {
                     btn.textContent = originalText;
                     btn.style.background = '#2196F3';
                 }, 1000);
             });
         },
         
         // 格式化时间显示
         formatTime(date) {
             if (!date) return '-';
             const d = new Date(date);
             return `${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}:${d.getSeconds().toString().padStart(2, '0')}`;
         },
         
         // 复制记录中的GeoJSON
         copyRecordGeoJSON(index) {
             const record = this.geojsonRecords[index];
             if (!record) return;
             
             navigator.clipboard.writeText(record.geojsonString).then(() => {
                 // 临时显示复制成功提示
                 const btn = event.target;
                 const originalText = btn.textContent;
                 btn.textContent = '已复制';
                 btn.style.background = '#4CAF50';
                 setTimeout(() => {
                     btn.textContent = originalText;
                     btn.style.background = '#2196F3';
                 }, 1000);
             }).catch(err => {
                 console.error('复制失败:', err);
                 // 降级方案
                 const textArea = document.createElement('textarea');
                 textArea.value = record.geojsonString;
                 document.body.appendChild(textArea);
                 textArea.select();
                 document.execCommand('copy');
                 document.body.removeChild(textArea);
                 
                 const btn = event.target;
                 const originalText = btn.textContent;
                 btn.textContent = '已复制';
                 btn.style.background = '#4CAF50';
                 setTimeout(() => {
                     btn.textContent = originalText;
                     btn.style.background = '#2196F3';
                 }, 1000);
             });
         },
         
         // 查看记录中的完整GeoJSON
         viewRecordGeoJSON(index) {
             const record = this.geojsonRecords[index];
             if (!record) return;
             
             // 显示在弹窗中
             alert(`GeoJSON记录 ${index + 1}:\n\n${record.geojsonString}`);
         },
         
         // 删除记录
         deleteRecord(index) {
             if (confirm(`确定要删除第 ${index + 1} 条记录吗？`)) {
                 const record = this.geojsonRecords[index];
                 if (record) {
                     // 删除对应的多边形实体
                     if (record.polygonEntity) {
                         this.viewer.entities.remove(record.polygonEntity);
                     }
                     if (record.outlineEntity) {
                         this.viewer.entities.remove(record.outlineEntity);
                     }
                 }
                 // 从数组中删除记录
                 this.geojsonRecords.splice(index, 1);
             }
         }
    }
}).mount('#app');
</script>
</body>
</html>
    